#include "WxFreeTypeTextMapper2D.h"
#include "WxvtkFTGLChineseCharacterMapper.h"
#include "WxvtkTextPropertyUnicode.h"
#include "WxFreeTypeText.h"

#include "vtkProperty2D.h"
#include "vtkLineSource.h"
#include "vtkPolyDataMapper2D.h"
#include "vtkActor2D.h"
using namespace mitk;
WxFreeTypeTextMapper2D::WxFreeTypeTextMapper2D(void):m_fontSize(10),m_shadow(true)//,m_shadowOffset(1)
{

}

WxFreeTypeTextMapper2D::~WxFreeTypeTextMapper2D(void)
{
	for (TextMapType::iterator it=m_TextCollection.begin();it!=m_TextCollection.end();it++)
	{
		if ((it->second)!=NULL)
		{
                   mitk::BaseRenderer* renderer= static_cast<mitk::BaseRenderer*>(it->first);
                    if((renderer!=NULL)&&(renderer->GetVtkRenderer()!=NULL)) renderer->GetVtkRenderer()->RemoveActor(it->second);
                    (it->second)->Delete();
		}
	
	}
}

const mitk::WxFreeTypeText *mitk::WxFreeTypeTextMapper2D::GetInput(void)
{
        return static_cast<const mitk::WxFreeTypeText * > ( GetData() );
}

void WxFreeTypeTextMapper2D::ApplyProperties(mitk::BaseRenderer* renderer)
{
        const mitk::DataNode* node=GetDataNode();
	if( node == NULL )
		return;
	node->GetStringProperty("FontFileName",m_fontFileName);
	node->GetIntProperty("FontSize",m_fontSize);
	node->GetBoolProperty("Shadow",m_shadow);
	node->GetFloatProperty("EffectiveDistance",m_EffectiveDistance);

//	node->GetIntProperty("ShadowOffset",m_shadowOffset);

}


void WxFreeTypeTextMapper2D::MitkRenderOpaqueGeometry(mitk::BaseRenderer* renderer)
{
        const mitk::DataNode* node=GetDataNode();
	if( node == NULL )
		return;



	// @FIXME: Logik fuer update
	bool updateNeccesary=true;

	if (updateNeccesary) 
	{

                mitk::WxFreeTypeText::Pointer input  = const_cast<mitk::WxFreeTypeText*>(this->GetInput());

		// Get the TimeSlicedGeometry of the input object
		const TimeSlicedGeometry* inputTimeGeometry = input->GetTimeSlicedGeometry();
		if (( inputTimeGeometry == NULL )  )
		{
			return;
		}

		//
		// get the world time
		//
                const Geometry2D* worldGeometry = renderer->GetCurrentWorldGeometry2D();
                assert( worldGeometry != NULL );
                //ScalarType time = worldGeometry->GetTimeBounds()[ 0 ];

		//
		// convert the world time in time steps of the input object
		//
		/*int timeStep=0;
		if ( time > ScalarTypeNumericTraits::NonpositiveMin() )
		timeStep = inputTimeGeometry->MSToTimeStep( time );
		if ( inputTimeGeometry->IsValidTime( timeStep ) == false )
		{
		return;
		}*/

		const char* text=input->GetText();
		if ( text == NULL) 
		{
			return;
		}
		Point3D Ori=input->GetOrigin();
		Point2D ori2d;		
                const DisplayGeometry* displayGeometry = renderer->GetDisplayGeometry();

                assert(displayGeometry!=NULL);

		//apply color and opacity read from the PropertyList
		ApplyProperties(renderer);
		
		vtkTextProperty* textPrpo=NULL;
		vtkActor2D* textActor=NULL; 
                WxvtkFTGLChineseCharacterMapper* textMapper=NULL;

		for (TextMapType::iterator it=m_TextCollection.begin();it!=m_TextCollection.end();it++)
		{
			if(((it->first)==(void*)renderer))
			{
				if ((it->second)!=NULL)
				{
					textActor=it->second;
                                        textMapper=(WxvtkFTGLChineseCharacterMapper*)textActor->GetMapper();
					textPrpo=(vtkTextProperty*)textActor->GetProperty();
				}
				else
				{
                                        textMapper=WxvtkFTGLChineseCharacterMapper::New();
                                        textMapper->SetTextProperty(WxvtkTextPropertyUnicode::New());
					textActor=vtkActor2D::New();
					textActor->SetMapper(textMapper);
					it->second=textActor;
				}			
			}
		}
		if (textActor==NULL)
		{
                        textMapper=WxvtkFTGLChineseCharacterMapper::New();
                        WxvtkTextPropertyUnicode* tprpo=WxvtkTextPropertyUnicode::New();
                        tprpo->SetFontFileName(m_fontFileName.c_str());
                        textMapper->SetTextProperty(tprpo);
                        tprpo->Delete();
			textActor=vtkActor2D::New();
			textActor->SetMapper(textMapper);
                        textMapper->Delete();
                        m_TextCollection[(void*)renderer]=textActor;
                        vtkRenderer* vtkren=renderer->GetVtkRenderer();
                        vtkren->AddActor(textActor);

		}

		displayGeometry->Map(Ori,ori2d);
                displayGeometry->WorldToDisplay(ori2d, ori2d);
		textMapper->SetInput(text);
                textActor->SetPosition(ori2d[0],ori2d[1]);


		int size[2];
		textMapper->GetSize(NULL,size);
		if (memcmp(size,m_size,sizeof(int)*2)!=0)
		{
			m_size[0]=size[0];
			m_size[1]=size[1];
		}
		
	

                if((worldGeometry->Distance(Ori)>m_EffectiveDistance)||(IsVisible(renderer)==false))
                    textActor->VisibilityOff();
                else
                    textActor->VisibilityOn();

		float color[3];
		node->GetColor(color);
                WxvtkTextPropertyUnicode* tprpo=dynamic_cast<WxvtkTextPropertyUnicode*>(textMapper->GetTextProperty());
		if (tprpo)
		{
			tprpo->SetFontFileName(m_fontFileName.c_str());
                        tprpo->SetColor(color[0],color[1],color[2]);
			tprpo->SetFontSize(m_fontSize);
			tprpo->SetShadow(m_shadow);
			//tprpo->SetShadowOffset(m_shadowOffset);
			float opacity;
			node->GetOpacity(opacity,renderer);
			tprpo->SetOpacity(opacity);
	
		}
		//vtkRenderer* vtkren=renderer->GetVtkRenderer();

        }
}
void WxFreeTypeTextMapper2D::MitkRenderTranslucentGeometry(mitk::BaseRenderer* renderer)
{
}
#if ( ( VTK_MAJOR_VERSION >= 5 ) && ( VTK_MINOR_VERSION>=2)  )
void WxFreeTypeTextMapper2D::MitkRenderVolumetricGeometry(mitk::BaseRenderer* /*renderer*/)
{

}
#endif
void WxFreeTypeTextMapper2D::MitkRenderOverlay(mitk::BaseRenderer* renderer)
{

}

void WxFreeTypeTextMapper2D::SetDefaultProperties(mitk::DataNode* node, mitk::BaseRenderer* renderer, bool overwrite)
{
	//node->AddProperty( "line width", mitk::IntProperty::New(2), renderer, overwrite ); // width of the line from one point to another
	//node->AddProperty( "point line width", mitk::IntProperty::New(1), renderer, overwrite ); //width of the cross marking a point
	//node->AddProperty( "point 2D size", mitk::IntProperty::New(8), renderer, overwrite ); // length of the cross marking a point // length of an edge of the box marking a point
	//node->AddProperty( "show contour", mitk::BoolProperty::New(false), renderer, overwrite ); // contour of the line between points
	//node->AddProperty( "show points", mitk::BoolProperty::New(true), renderer, overwrite ); //show or hide points 
	//node->AddProperty( "show distances", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide distance measure (not always available)
	//node->AddProperty( "distance decimal digits", mitk::IntProperty::New(2), renderer, overwrite ); //set the number of decimal digits to be shown
	//node->AddProperty( "show angles", mitk::BoolProperty::New(false), renderer, overwrite ); //show or hide angle measurement (not always available)
	//node->AddProperty( "show distant lines", mitk::BoolProperty::New(false), renderer, overwrite ); //show the line between to points from a distant view (equals "always on top" option)

	node->AddProperty("FontFileName",mitk::StringProperty::New("simyou.ttf"),renderer,overwrite);
	node->AddProperty("FontSize",mitk::IntProperty::New(10),renderer,overwrite);
	//node->AddProperty("ShadowOffset",mitk::IntProperty::New(1),renderer,overwrite);
	node->AddProperty("Shadow",mitk::BoolProperty::New(true),renderer,overwrite);
	node->AddProperty("EffectiveDistance",mitk::FloatProperty::New(5),renderer,overwrite);

	Superclass::SetDefaultProperties(node, renderer, overwrite);
}
